package com.ztools.wx.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ztools.api.service.pc.PcPayService;
import com.ztools.common.config.rabbitMq.config.ExchangeConfig;
import com.ztools.common.model.wx.payment.Cart;
import com.ztools.common.model.wx.payment.CartItem;
import com.ztools.common.util.common.Result;
import com.ztools.common.util.common.ResultCode;
import com.ztools.common.util.common.enumUnit.RoutingKeyEnum;
import com.ztools.wx.service.WxPayService;
import com.ztools.wx.service.payment.weChatPay.WeChatPayService;
import org.apache.dubbo.config.annotation.Reference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import static com.ztools.common.util.wx.RedisUtil.PAYMENT_TO_QUERY_KEY;
import static com.ztools.wx.config.WxSysConstants.TEST_URL;
import static com.ztools.wx.config.WxSysConstants.WX_SERVER_URL;

/**
 * @Author: seeTools
 * @Date: 2023/6/3  22:01
 * @Version 1.0
 */
@Service
public class WxPayServiceImpl implements WxPayService {

    private final Logger logger = LoggerFactory.getLogger(getClass());

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Resource
    private WeChatPayService weChatPayService;

    @Reference(version = "1.0", check = false, timeout = 6000)
    private PcPayService pcPayService;
    @Resource
    private RabbitTemplate rabbitTemplate;

    /**
     * 商品结算
     *
     * @param map map
     * @return String
     */
    @Override
    public Result storePay(Map<String, String> map) {
        logger.info("@storePay#in");
        String params = map.get("params");
        String openid = map.get("openid");
        if (StrUtil.isEmpty(params) || !JSONUtil.isJson(params)) {
            return Result.error("参数不合法");
        }
        Cart cart = JSONUtil.toBean(params, Cart.class);
        cart.setPaymentNo(genPaymentNo(cart));
        cart.setMemberId(cart.getMemberId());
        List<CartItem> cartList = cart.getCartList();
        logger.info("cartInfo: {}", cart);
        // 判断库存以及购买限制是否合法
        Result result = pcPayService.validateOnlineStockCart(cart);
        if (ResultCode.SUCCESS.getCode() != result.getCode()) {
            return result;
        }
        if (cartList.size() > 0) {
            Map<String, String> orderMap = new HashMap<>(10);
            // 订单金额-单位为分
            orderMap.put("amount", String.valueOf(cart.getPayAmount().intValue()));
            // 支付订单号
            orderMap.put("paymentNo", cart.getPaymentNo());
            // 商品描述
            orderMap.put("desc", "商品消费:" + cart.getAmount() + "元");
            // openid
            orderMap.put("openid", openid);
            logger.info("@storePay#orderMap={}", orderMap);
            // 如果是测试环境，则直接跳过支付
            if (WX_SERVER_URL.contains(TEST_URL)) {
                // 直接添加到待推送队列
                rabbitTemplate.convertAndSend(ExchangeConfig.TOPIC_EXCHANGE, RoutingKeyEnum.ORDER_KEY.getRoutingKey() + cart.getPaymentNo(), JSONUtil.toJsonStr(cart));
//                stringRedisTemplate.opsForValue().set(CART_TO_SEND_KEY_PREFIX + cart.getPaymentNo(), JSONUtil.toJsonStr(cart), 1L, TimeUnit.DAYS);
                return Result.success("下单成功");
            }
            String res = weChatPayService.order(orderMap);
            if (StrUtil.isNotEmpty(res)) {
                // 待查询支付订单号(第三方)
                stringRedisTemplate.opsForValue().set(PAYMENT_TO_QUERY_KEY + cart.getPaymentNo(), JSONUtil.toJsonStr(cart), 1L, TimeUnit.DAYS);
                rabbitTemplate.convertAndSend(ExchangeConfig.TOPIC_EXCHANGE, RoutingKeyEnum.ORDER_KEY.getRoutingKey() + cart.getPaymentNo(), JSONUtil.toJsonStr(cart));
            }
            logger.info("@storePay#out,{}", StrUtil.isNotEmpty(res) ? "success" : "error");
            return Result.success(res);
        }
        logger.info("@storePay#out");
        return null;
    }

    /**
     * 订单号生成
     *
     * @param cart cart
     * @return String
     */
    private String genPaymentNo(Cart cart) {
        // 订单号：会员ID:时间戳:5位随机数:W
        return cart.getMemberId() + ":" +
                DateUtil.format(new Date(), "yyyyMMddHHmmssSSS") + ":" +
                RandomUtil.randomNumbers(5) + ":W";
    }


}
